package com.talentech.xproberlib;

import static com.talentech.xproberlib.Utils.log;
import android.app.Activity;
import android.support.v4.view.MotionEventCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;

public class GestureHooks
{
	public static XC_MethodHook dispatchTouchEventHook = new XC_MethodHook()
	{
		// 右边缘：SizeX + OffsizeX应等于1
		float triggerZoneSizeX = 0.05f;
		float triggerZoneSizeY = 0.4f;

		float triggerZoneOffsetX = 0.95f;
		float triggerZoneOffsetY = 0.15f;

		float triggerLengthX = 0.2f;
		float triggerLengthY = 0.0f;

		float startX = 0;
		float startY = 0;
		boolean inGesture = false;

		protected void beforeHookedMethod(MethodHookParam param) throws Throwable
		{
			if (!param.method.getName().equals("dispatchTouchEvent"))
			{
				log("Incorrect hook point");
				return;
			}

			if (param.args[0] == null)
			{
				return;
			}

			// log("dispatchTouchEvent");

			MotionEvent ev = (MotionEvent) param.args[0];
			int pointerIndex = ev.getActionIndex();
			int pointerId = ev.getPointerId(pointerIndex);

			if (pointerId != 0)
			{
				return; // 只受理主手指的操作。此后pointerIndex必然指主手指的。
			}

			Activity activity = (Activity) param.thisObject;
			DisplayMetrics dm = activity.getResources().getDisplayMetrics();
			int w = dm.widthPixels;
			int h = dm.heightPixels;

			float x = ev.getX(pointerIndex);
			float y = ev.getY(pointerIndex);
			
			int action = MotionEventCompat.getActionMasked(ev);
			switch (action)
			{
			case (MotionEvent.ACTION_DOWN):
//				log("Action was DOWN");
				if ((x >= w * triggerZoneOffsetX) && (x <= w * (triggerZoneSizeX + triggerZoneOffsetX)) && (y >= h * triggerZoneOffsetY)
						&& (y <= h * (triggerZoneSizeY + triggerZoneOffsetY)))
				{
					inGesture = true;
					startX = x;
					startY = y;
				}
				else
				{
					inGesture = false;
				}
				break;
			case (MotionEvent.ACTION_MOVE):
//				log("Action was MOVE");
				break;
			case (MotionEvent.ACTION_UP):
//				log("Action was UP");
				if (inGesture == true)
				{
					if ((Math.abs(x - startX) >= triggerLengthX) && (Math.abs(y - startY) >= triggerLengthY))
					{
						log("Fire!");
						activity.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
						activity.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
					}
					inGesture = false;
				}

				break;
			case (MotionEvent.ACTION_OUTSIDE):
//				log("Movement occurred outside bounds " + "of current screen element");
				break;
			default:
			}

			// log("pointerIndex: " + ev.getActionIndex() + ", pointerId: " + pointerId);

//			log(inGesture + "X: " + x + ", Y: " + y + ", W: " + w + ", H: " + h);
		}

		protected void afterHookedMethod(MethodHookParam param) throws Throwable
		{
		}
	};
}
